package cn.hiapi.shop.api;

import cn.hiapi.basic.ResponseEntity;
import cn.hiapi.basic.controller.BasicController;
import cn.hiapi.basic.entity.BasicEntity;
import cn.hiapi.basic.exception.BasicException;
import cn.hiapi.basic.jpa.pageable.QueryWrapper;
import cn.hiapi.basic.redis.data.LockConst;
import cn.hiapi.basic.security.TokenGet;
import cn.hiapi.basic.token.Token;
import cn.hiapi.interfaces.DispatchContext;
import cn.hiapi.interfaces.ILockService;
import cn.hiapi.interfaces.user.IUserService;
import cn.hiapi.shop.entity.shop.ShopLinkUser;
import cn.hiapi.shop.query.ScanOrderQuery;
import cn.hiapi.shop.service.shop.ShopLinkUserService;
import cn.hiapi.shopkeeper.entity.activity.ActivityCodeRecord;
import cn.hiapi.shopkeeper.entity.order.ActivityOrder;
import cn.hiapi.shopkeeper.enums.OrderStatus;
import cn.hiapi.shopkeeper.service.activity.ActivityCodeRecordService;
import cn.hiapi.shopkeeper.service.activity.ActivityFactory;
import cn.hiapi.shopkeeper.service.order.ActivityOrderService;
import cn.hiapi.user.entity.User;
import cn.hiapi.user.service.UserService;
import cn.hiapi.utils.JsonUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author AdinZ
 * @date 2023/2/5 17:28
 */
@RestController
@RequestMapping("/shop/scan-code")
public class ScanOrderController extends BasicController {
    private final DispatchContext dispatchContext;

    public ScanOrderController(DispatchContext dispatchContext) {
        this.dispatchContext = dispatchContext;
    }

    @ApiOperation(value = "获取订单", notes = "获取订单", nickname = "AdinZ")
    @GetMapping("")
    public ResponseEntity scanCode(@RequestParam("code") String code,
                                   @RequestParam("shopId") long shopId) {
        ActivityCodeRecord record = this.dispatchContext.getServiceOne(ActivityCodeRecordService.class).getCode(code);
        if (record == null) return toError("核销码不正确");
        if (shopId != record.getShopId()) return toError("非本店核销码");
        Token<User> token = TokenGet.get();
        this.dispatchContext.getServiceOne(ShopLinkUserService.class).verifyShop(token.getFid(), shopId);
        ActivityOrder order = this.dispatchContext.getServiceOne(ActivityOrderService.class).get(record.getOid());
        if (order == null) return toError("订单不存在");
        if (order.getShopId() != shopId) return toError("非本店订单");

        JSONObject data = JsonUtils.builder()
                .put("id", order.getId())
                .put("thumb", order.getThumb())
                .put("title", order.getTitle())
                .put("price", order.getPrice())
                .put("number", order.getNumber())
                .put("useStart", order.getUseStart())
                .put("useEnd", order.getUseEnd())
                .put("totalMoney", order.getTotalMoney())
                .put("payment", order.getPayment())
                .put("discount", order.getDiscount())
                .put("sugar", order.getSugar())
                .put("status", order.getStatus())
                .put("type", order.getActivityType())
                .put("codeStatus", record.getStatus())
                .build();
        if (StringUtils.isNotEmpty(order.getExpandText())) {
            data.put("expand", JSON.parseObject(order.getExpandText()));
        }
        return toSuccess(Lists.newArrayList(data));
    }


    @ApiOperation(value = "核销", notes = "核销", nickname = "AdinZ")
    @GetMapping("/check") @Transactional
    public ResponseEntity check(@RequestParam("code") String code,
                                @RequestParam("shopId") long shopId) {
        if (StringUtils.isBlank(code))
            return toError("请输入核销码");

        String lock = LockConst.getLock("scan-code-check", code);
        try {
            this.dispatchContext.getServiceOne(ILockService.class).lockThr(lock);
            ActivityCodeRecord record = this.dispatchContext.getServiceOne(ActivityCodeRecordService.class).getCode(code);
            if (record == null) return toError("核销码不正确");
            if (shopId != record.getShopId()) return toError("非本店核销码");
            if (record.getStatus() == 1) return toError("核销码已被使用");
            if (record.getStatus() == 2) return toError("核销码已作废");
            if (record.getStatus() != 0) return toError("核销码状态错误 - " + record.getStatus());
            Token<User> token = TokenGet.get();
            this.dispatchContext.getServiceOne(ShopLinkUserService.class).verifyShop(token.getFid(), shopId);
            record.setStatus(1);
            record.setUpdated(System.currentTimeMillis());
            this.dispatchContext.getServiceOne(ActivityCodeRecordService.class).save(record);
            this.dispatchContext.getServiceOne(ActivityOrderService.class).checkOrder(shopId, record.getOid());
            return toSuccess();
        } finally {
            this.dispatchContext.getServiceOne(ILockService.class).unlock(lock);
        }

    }


    @ApiOperation(value = "核销记录", notes = "核销记录", nickname = "AdinZ")
    @PostMapping("/record")
    public ResponseEntity record(@RequestBody ScanOrderQuery query) {
        Token<User> token = TokenGet.get();
        this.dispatchContext.getServiceOne(ShopLinkUserService.class).verifyShop(token.getFid(), query.getShopId());
        QueryWrapper wrapper = query.getQueryWrapper();
        if (StringUtils.isNotEmpty(query.getKey())) {
            if (StringUtils.isNumeric(query.getKey())) {
                if (StringUtils.length(query.getKey()) == 11) {
                    Long uid = this.dispatchContext.getServiceOne(IUserService.class).getUid(token.getMerchantId(), query.getKey());
                    if (uid == null) throw new BasicException("手机号不存在");
                    wrapper.eq("uid", uid);
                } else {
                    wrapper.eq("oid", Long.valueOf(query.getKey()));
                }
            }
        }
        ResponseEntity<List<ActivityCodeRecord>> response = this.dispatchContext.getServiceOne(ActivityCodeRecordService.class).findPage(wrapper, query.getPageable());
        List<JSONObject> collect = response.getData().stream().map(e -> {
            ActivityOrder order = this.dispatchContext.getServiceOne(ActivityOrderService.class).get(e.getOid());
            if (order != null) {
                JSONObject object = JSON.parseObject(StringUtils.isNotEmpty(order.getExpandText()) ? order.getExpandText() : "{}");
                Object user = this.dispatchContext.getServiceOne(IUserService.class).fieldBase(order.getBuyerId());
                JSONObject data = JsonUtils.builder()
                        .put("id", order.getId())
                        .put("thumb", order.getThumb())
                        .put("expand", object)
                        .put("title", order.getTitle())
                        .put("price", order.getPrice())
                        .put("number", order.getNumber())
                        .put("useStart", order.getUseStart())
                        .put("useEnd", order.getUseEnd())
                        .put("totalMoney", order.getTotalMoney())
                        .put("payment", order.getPayment())
                        .put("discount", order.getDiscount())
                        .put("sugar", order.getSugar())
                        .put("created", order.getCreated())
                        .put("status", order.getStatus())
                        .put("type", order.getActivityType())
                        .put("codeStatus", e.getStatus())
                        .put("user", user)
                        .build();
                return data;
            } else {
                return null;
            }
        }).filter(e -> e != null).collect(Collectors.toList());
        return toSuccess(collect, response.getTotal(), response.getTotalPage());
    }

    @ApiOperation(value = "核销统计", notes = "核销统计", nickname = "AdinZ")
    @GetMapping("/total")
    public ResponseEntity total(@RequestParam("shopId") long shopId) {
        //已核销金额, 未核销金额
        Token<Object> token = TokenGet.get();
        this.dispatchContext.getServiceOne(ShopLinkUserService.class).verifyShop(token.getFid(), shopId);
        BigDecimal waitUse = this.dispatchContext.getServiceOne(ActivityOrderService.class).totalSumWaitUseAmount(shopId);
        BigDecimal complete = this.dispatchContext.getServiceOne(ActivityOrderService.class).totalSumComplete(shopId);
        return toSuccess(JsonUtils.builder()
                .put("waitTotal", waitUse)
                .put("complete", complete)
                .build());
    }


}
